#ifndef _WX_GENERIC_ANIMATEH__
#define _WX_GENERIC_ANIMATEH__

#include "wx/bitmap.h"

WX_DECLARE_LIST_WITH_DECL( wxAnimationDecoder, wxAnimationDecoderList, class WXDLLIMPEXP_ADV );

class WXDLLIMPEXP_ADV wxAnimation : public wxAnimationBase {
  public:
    wxAnimation() {}
    wxAnimation( const wxString &name, wxAnimationType type = wxANIMATION_TYPE_ANY ) { LoadFile( name, type ); }
    virtual bool IsOk() const { return m_refData != NULL; }
    virtual unsigned int GetFrameCount() const;
    virtual int GetDelay( unsigned int i ) const;
    virtual wxImage GetFrame( unsigned int i ) const;
    virtual wxSize GetSize() const;
    virtual bool LoadFile( const wxString& filename,wxAnimationType type = wxANIMATION_TYPE_ANY );
    virtual bool Load( wxInputStream& stream,wxAnimationType type = wxANIMATION_TYPE_ANY );
    wxPoint GetFramePosition( unsigned int frame ) const;
    wxSize GetFrameSize( unsigned int frame ) const;
    wxAnimationDisposal GetDisposalMethod( unsigned int frame ) const;
    wxColour GetTransparentColour( unsigned int frame ) const;
    wxColour GetBackgroundColour() const;
  protected:
    static wxAnimationDecoderList sm_handlers;
  public:
    static inline wxAnimationDecoderList& GetHandlers() { return sm_handlers; }
    static void AddHandler( wxAnimationDecoder *handler );
    static void InsertHandler( wxAnimationDecoder *handler );
    static const wxAnimationDecoder *FindHandler( wxAnimationType animType );

    static void CleanUpHandlers();
    static void InitStandardHandlers();

    DECLARE_DYNAMIC_CLASS( wxAnimation )
};

class WXDLLIMPEXP_ADV wxAnimationCtrl: public wxAnimationCtrlBase {
  public:
    wxAnimationCtrl() { Init(); }
    wxAnimationCtrl( wxWindow *parent, wxWindowID id, const wxAnimation& anim = wxNullAnimation,
                     const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
                     long style = wxAC_DEFAULT_STYLE, const wxString& name = wxAnimationCtrlNameStr ) {
      Init();
      Create( parent, id, anim, pos, size, style, name );
    }

    void Init();

    bool Create( wxWindow *parent, wxWindowID id, const wxAnimation& anim = wxNullAnimation,
                 const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
                 long style = wxAC_DEFAULT_STYLE, const wxString& name = wxAnimationCtrlNameStr );
    ~wxAnimationCtrl();
  public:
    virtual bool LoadFile( const wxString& filename, wxAnimationType type = wxANIMATION_TYPE_ANY );
    virtual void Stop();
    virtual bool Play() { return Play( true ); }
    virtual bool IsPlaying() const { return m_isPlaying; }
    void SetAnimation( const wxAnimation &animation );
    wxAnimation GetAnimation() const { return m_animation; }
    virtual void SetInactiveBitmap( const wxBitmap &bmp );
    virtual bool SetBackgroundColour( const wxColour& col );
  public:
    void OnPaint( wxPaintEvent& event );
    void OnTimer( wxTimerEvent& event );
    void OnSize( wxSizeEvent& event );
  public:
    void SetUseWindowBackgroundColour( bool useWinBackground = true ) { m_useWinBackgroundColour = useWinBackground; }
    bool IsUsingWindowBackgroundColour() const { return m_useWinBackgroundColour; }
    bool Play( bool looped );
    void DrawCurrentFrame( wxDC& dc );
    wxBitmap& GetBackingStore() { return m_backingStore; }
  protected:
    void FitToAnimation();
    void DisposeToBackground();
    void DisposeToBackground( wxDC& dc );
    void DisposeToBackground( wxDC& dc, const wxPoint &pos, const wxSize &sz );
    void IncrementalUpdateBackingStore();
    bool RebuildBackingStoreUpToFrame( unsigned int );
    void DrawFrame( wxDC &dc, unsigned int );
    virtual void DisplayStaticImage();
    virtual wxSize DoGetBestSize() const;
  protected:
    unsigned int  m_currentFrame;     // Current frame
    bool          m_looped;           // Looped, or not
    wxTimer       m_timer;            // The timer
    wxAnimation   m_animation;        // The animation
    bool          m_isPlaying;        // Is the animation playing?
    bool          m_useWinBackgroundColour; // Use animation bg colour or window bg colour?
    wxBitmap      m_backingStore;     // The frames are drawn here and then blitted
  private:
    typedef wxAnimationCtrlBase base_type;
    DECLARE_DYNAMIC_CLASS( wxAnimationCtrl )
    DECLARE_EVENT_TABLE()
};

#endif
